<template>
  <div class="avic-modal-select">
    <div @click="handleInputClick"><slot /></div>
    <a-input
      v-if="!$slots.default"
      ref="showValueComp"
      :value="select.showFields"
      :disabled="disabled"
      :placeholder="!disabled ? placeholder : ''"
      :readonly="disabledInput"
      @change="handleChange"
      @dblclick="showSelectModal"
      @click="handleInputClick"
      @blur="inputBlur"
      @focus="handleFocus"
      @pressEnter="handlePressEnter"
    >
      <template v-if="iconPosition == 'after'" v-slot:suffix>
        <avic-icon :svg="iconType" title="点击选择" @click="showSelectModal" />
        <avic-icon
          v-if="!disabled && allowClear"
          v-show="select.showFields !== ''"
          title="点击清空"
          class="icon-clear"
          svg="avic-close-circle-fill"
          @click="handleClear"
        />
      </template>
      <template v-if="iconPosition == 'before'" v-slot:prefix>
        <avic-icon :svg="iconType" title="点击选择" @click="showSelectModal" />
        <avic-icon
          v-if="!disabled && allowClear"
          v-show="select.showFields !== ''"
          title="点击清空"
          class="icon-clear"
          svg="avic-close-circle-fill"
          @click="handleClear"
        />
      </template>
    </a-input>
    <AvicModal
      v-if="visible"
      v-bind="$attrs"
      :visible="visible"
      :title="title"
      :width="width"
      :height="height"
      :body-style="{ padding: 0 }"
      @cancel="hideSelectModal"
    >
      <AvicSplit v-if="multiple">
        <AvicPane :size="contentWidth">
          <component
            :is="selectComponent"
            v-bind="{ ...$attrs }"
            :value="value"
            :default-selected-row-keys="defaultSelectRowKeys"
            @select="handleSelect"
            @handleRowDblClick="handleRowDblClick"
          />
        </AvicPane>
        <AvicPane>
          <div style="padding: 10px; width: 100%; border-bottom: 2px solid #f0f2f5; display: inline-flex">
            <div style="text-align: left; flex: 1">已选数据</div>
            <div style="text-align: right; flex: initial">
              <delete-outlined @click="handleDelAllData()" />
            </div>
          </div>
          <a-list style="padding: 15px; height: 100%; overflow: auto" item-layout="horizontal" :data-source="selectedData">
            <template #renderItem="{ item }">
              <a-list-item>
                <a-list-item-meta :description="item[showField]">
                  {{ item[showField] }}
                </a-list-item-meta>
                <close-outlined @click="handleDelData(item)" />
              </a-list-item>
            </template>
          </a-list>
        </AvicPane>
      </AvicSplit>
      <component
        :is="selectComponent"
        v-else
        v-bind="{ ...$attrs }"
        :value="value"
        :default-selected-row-keys="defaultSelectRowKeys"
        @select="handleSelect"
        @handleRowDblClick="handleRowDblClick"
      />
      <template v-slot:footer>
        <a-button type="primary" @click="handleConfirm">确定</a-button>
        <a-button type="primary" ghost @click="hideSelectModal">取消</a-button>
      </template>
    </AvicModal>
  </div>
</template>
<script setup lang="ts">
import { Form } from 'ant-design-vue';
const { proxy } = getCurrentInstance();
/**
 * focus失去焦点回调
 * pressEnter 回车的回调
 * change 数据改变回调
 * input 双向绑定回调
 * selectConfirm 选中数据对象回调
 * clear 清除回调
 */
const $emit = defineEmits(['focus', 'blur', 'pressEnter', 'change', 'input', 'selectConfirm', 'clear', 'update:value']);
const props = defineProps({
  /** 双向绑定的值 */
  value: { type: String, default: '' },
  /** 标题 */
  title: { type: String, default: '选择' },
  /** 弹框宽度 */
  height: { type: String, required: false, default: '580px' },
  /** 弹窗高度 */
  width: { type: String, required: false, default: '1200px' },
  /** 要选择的单表组件对象 */
  selectComponent: { type: Object, default: null },
  /** 是否多选 ，默认：否 */
  multiple: { type: Boolean, default: false },
  /** 是否展示清空图标 */
  allowClear: { type: Boolean, default: false },
  /** 用于展示的字段名称 */
  showField: { type: String, default: '' },
  /** 存储值对应字段名 */
  valueField: { type: String, default: 'id' },
  /** 默认显示内容 */
  defaultShowValue: { type: String, default: '' },
  /** 输入框提示 */
  placeholder: { type: String, required: false, default: '' },
  /** 是否禁用控件 */
  disabled: { type: Boolean, required: false, default: false },
  /** 否禁止输入 */
  disabledInput: { type: Boolean, required: false, default: true },
  /** input的图标类型 */
  iconType: { type: String, default: 'SelectOutlined' },
  /** input的图标位置 */
  iconPosition: {
    type: String as PropType<'after' | 'before'>,
    default: 'after'
  },
  /**
   * 确认时自定义异步校验函数及校验提示信息
   * @type Promise
   * @param 参数：{selectedData}
   *              selectedData: Array<Record>
   * @returns Boolean true:校验通过；false:校验不通过
   */
  checkBeforeConfirm: {
    type: [Function, null],
    default: null
  },
  /** 多选时，内容宽度 ,支持百分比和具体宽高，百分比直接写数字，具体宽写 数字px */
  contentWidth: {
    type: [Number, String],
    default: '80'
  }
});
const showValueComp = ref();
const visible = ref(false);
const isFilled = ref(false);
const selectedData = ref([]);
const tableSelectedData = ref([]);
const select = ref({ valueFields: '', showFields: '' });
const formItemContext = Form.useInjectFormItemContext();
const defaultSelectRowKeys = ref([]);
watch(
  () => props.value,
  (newValue) => {
    select.value.valueFields = newValue || '';
    if (!newValue) {
      select.value.showFields = '';
    }
  },
  { immediate: true }
);
watch(
  () => props.defaultShowValue,
  (newValue) => {
    select.value.showFields = newValue || '';
  },
  { immediate: true }
);
watch(
  () => visible.value,
  (newValue) => {
    if (newValue && props.multiple) {
      initValue();
    }
  },
  { immediate: true }
);
watch(
  () => selectedData.value,
  () => {
    getDefaultSelectRowKeys();
  },
  { immediate: true }
);
/** modal显示 */
function showSelectModal() {
  if (!props.disabled) {
    visible.value = true;
    selectedData.value = []; // 初始化选择的值为空，以免影响其他使用该组件地方
    tableSelectedData.value = [];
  }
}
function initValue() {
  const valueFieldsValue = select.value.valueFields;
  const showFieldsValue = select.value.showFields;
  if (valueFieldsValue && showFieldsValue) {
    const valueList = valueFieldsValue.split(';');
    const showFieldsList = showFieldsValue.split(';');
    for (let i = 0; i < valueList.length; i++) {
      const data = {};
      data[props.valueField] = valueList[i];
      data[props.showField] = showFieldsList[i];
      tableSelectedData.value.push(data);
    }
  }
  buildSelectData(true);
}
/** modal隐藏 */
function hideSelectModal() {
  if (showValueComp.value) {
    showValueComp.value.focus();
  }
  nextTick(() => {
    visible.value = false;
  });
}
/** 点击输入框获取焦点
 * @param {object} e 拖动事件
 */
function handleFocus(e) {
  // if (props.disabledInput && !isFilled.value) {
  //   showSelectModal();
  // }
  $emit('focus', e);
}
/** 点击enter键
 * @param {object} e 事件
 */
function handlePressEnter(e) {
  $emit('pressEnter', e);
}
/** 单击输入框 */
function handleInputClick() {
  if (props.disabledInput) {
    showSelectModal();
  }
}
/** 选中数据
 *  @param {array} data 选中得数据
 */
function handleSelect(data, selected) {
  if (!props.multiple) {
    selectedData.value = data;
  } else {
    tableSelectedData.value = data;
    buildSelectData(selected);
  }
}
function buildSelectData(selected) {
  if (selected !== undefined && !selected) {
    // 移除数据
    selectedData.value = proxy.$lodash.cloneDeep(selectedData.value).filter(
      (item) =>
        !tableSelectedData.value.some((obj) => {
          if (obj[props.valueField] === item[props.valueField]) {
            return true;
          }
          return false;
        })
    );
    return;
  }
  tableSelectedData.value.forEach((item) => {
    const getData = selectedData.value.filter((obj) => {
      if (obj[props.valueField] === item[props.valueField]) {
        return obj;
      }
      return null;
    });
    if (getData.length === 0) {
      selectedData.value.push(item);
    }
  });
  getDefaultSelectRowKeys();
}
function getDefaultSelectRowKeys() {
  const rowKeys = [];
  selectedData.value.forEach((item) => {
    rowKeys.push(item[props.valueField]);
  });
  defaultSelectRowKeys.value = rowKeys;
}
function handleDelAllData() {
  selectedData.value = [];
  getDefaultSelectRowKeys();
}
function handleDelData(record) {
  const data = proxy.$lodash.cloneDeep(selectedData.value);
  const getData = data.filter((item) => {
    if (record[props.valueField] !== item[props.valueField]) {
      return item;
    }
    return null;
  });
  selectedData.value = getData;
}
/** 点击modal确认按钮 */
function handleConfirm() {
  if (selectedData.value.length === 0) {
    proxy.$message.warning('请至少选择一条数据');
    return;
  }
  if (!props.multiple && selectedData.value.length > 1) {
    proxy.$message.warning('最多选择一条数据');
    return;
  }
  if (props.checkBeforeConfirm) {
    props.checkBeforeConfirm({ selectedData: selectedData.value }).then((result) => {
      if (result) {
        afterCheck();
      }
    });
  } else {
    afterCheck();
  }
}
function afterCheck() {
  const valueFieldsArr = [];
  const showFieldsArr = [];
  selectedData.value.map((item) => {
    valueFieldsArr.push(item[props.valueField] || '');
    showFieldsArr.push(item[props.showField] || '');
    return item;
  });
  const valueFields = valueFieldsArr.join(';');
  const showFields = showFieldsArr.join(';');
  select.value = { valueFields, showFields };
  $emit('change', select.value.valueFields);
  $emit('input', select.value.valueFields);
  $emit('update:value', select.value.valueFields);
  $emit('selectConfirm', selectedData.value);
  visible.value = false;
  isFilled.value = true;
  formItemContext?.onFieldChange && formItemContext.onFieldChange();
}
/**
 * 输入框值变化
 * @param {object} e 拖动事件
 */
function handleChange(e) {
  const oldValue = select.value.showFields;
  if (props.disabledInput) {
    select.value.showFields = oldValue;
  } else {
    select.value.valueFields = e.target.value;
    select.value.showFields = e.target.value;
    $emit('change', select.value.valueFields);
    $emit('input', select.value.valueFields);
    $emit('update:value', select.value.valueFields);
    const obj = {};
    obj[props.valueField] = select.value.showFields;
    obj[props.showField] = select.value.showFields;
    $emit('selectConfirm', [obj]);
    formItemContext?.onFieldChange && formItemContext.onFieldChange();
  }
}
/** 清除输入框 */
function handleClear() {
  select.value = { valueFields: '', showFields: '' };
  $emit('change', select.value.valueFields);
  $emit('input', select.value.valueFields);
  $emit('update:value', select.value.valueFields);
  $emit('clear');
  formItemContext?.onFieldChange && formItemContext.onFieldChange();
}
function inputBlur(e) {
  $emit('blur', e);
  // 触发表单字段的blur校验
  formItemContext?.onFieldBlur && formItemContext.onFieldBlur();
}
/** 双击回填
 * @param {array} data 双击选中回填得数据
 */
function handleRowDblClick(data) {
  selectedData.value = data;
  handleConfirm();
}
</script>
<style lang="less">
.avic-modal-select {
  .ant-input-affix-wrapper {
    // .ant-input:not(:last-child) {
    //   // padding-right: 44px;
    // }
    .ant-input-suffix {
      .anticon {
        cursor: pointer;
      }
      .icon-clear {
        // font-size: 1.2em;
        display: none;
        margin-left: 8px;
        .svg-icon {
        }
      }
    }
  }
  .ant-input-affix-wrapper:hover {
    .ant-input-suffix .icon-clear {
      display: inline-block;
    }
  }
}
</style>